/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package unc.pds.filemodel;

import java.rmi.RemoteException;
import java.util.Date;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import unc.pds.data.Consts;
import unc.pds.data.RootDataBeanRemote;
import unc.pds.data.RootDataBeanRemoteHome;
import unc.pds.model.CommentRemote;
import unc.pds.model.CommentRemoteHome;
import unc.pds.model.Model;
import unc.pds.model.ModelFactory;
import unc.pds.model.Postable;
import unc.pds.model.RoleRemote;
import unc.pds.model.RoleRemoteHome;
import unc.pds.model.UserRemote;
import unc.pds.util.Arch;
import unc.pds.util.ArchImpl;

/**
 *
 * @author ain
 */
public class Folder implements SessionBean, Model {

    private SessionContext context;
    private Long sessionKey;
    private RootDataBeanRemote dataBean;
    private static String default_object_type = Consts.OBJECT_TYPE__FOLDER;

    // <editor-fold defaultstate="collapsed" desc="EJB infrastructure methods. Click the + sign on the left to edit the code.">;
    // TODO Add code to acquire and use other enterprise resources (DataSource, JMS, enterprise bean, Web services)
    // TODO Add business methods or web service operations
    /**
     * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
     */
    public void setSessionContext(SessionContext aContext) {
        context = aContext;
    }

    /**
     * @see javax.ejb.SessionBean#ejbActivate()
     */
    public void ejbActivate() {
    }

    /**
     * @see javax.ejb.SessionBean#ejbPassivate()
     */
    public void ejbPassivate() {
    }

    /**
     * @see javax.ejb.SessionBean#ejbRemove()
     */
    public void ejbRemove() throws RemoteException {
    }

    // </editor-fold>;
    /**
     * See section 7.10.3 of the EJB 2.0 specification
     * See section 7.11.3 of the EJB 2.1 specification
     */
    /*public void ejbCreate() {
    }*/

    public void ejbCreate(unc.pds.data.RootDataBeanRemote rdb, Long nsessionKey) throws RemoteException {
        dataBean = rdb;
        sessionKey = nsessionKey;
        dataBean.setSessionKey(sessionKey);
    }

    public void ejbCreate(Long id, Long nsessionKey) throws NamingException, RemoteException {
        try {
            RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            dataBean = rdbrh.findByPrimaryKey(id);
        } catch (Exception e) {
            throw new EJBException(e.getLocalizedMessage());
        }
        sessionKey = nsessionKey;
        dataBean.setSessionKey(sessionKey);
    }

    public void ejbCreate(Arch doc, Long nsessionKey) throws CreateException, RemoteException {
        sessionKey = nsessionKey;
        try {
            if (doc.getChild(Consts.ARCH_F_TYPE) == null) {
                doc.addChild(new ArchImpl(Consts.ARCH_F_TYPE, Consts.OBJECT_TYPE__FOLDER));
            }
            RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            dataBean = rdbrh.create(doc,sessionKey);
            dataBean.setSessionKey(sessionKey);
        } catch (Exception nex) {
            throw new CreateException("Folder: CREATEbyDOC: " + nex.getLocalizedMessage());
        }       
    }

    public Date getDate() throws RemoteException{
        return dataBean.getCrDate();
    }

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method" or "Web Service > Add Operation")
    public Long getKey() throws RemoteException {
        return (Long) dataBean.getPrimaryKey();
    }

    public Model getParent() throws RemoteException {
        return ModelFactory.getByKey(dataBean.getParentID(),sessionKey);
    }

    public CommentRemote[] getComments() throws RemoteException {
        try {
            Arch doc = new ArchImpl("root", "");
            Arch name = new ArchImpl(Consts.ATTR__COMMENT_PARENT, getKey().toString());
            doc.addChild(name);
            RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            Collection bean = rdbrh.findMByFieldSet(doc, Consts.OBJECT_TYPE__COMMENT);
            if (!bean.isEmpty()) {
                CommentRemoteHome drh =
                    (CommentRemoteHome) (new InitialContext()).lookup("ejb/Comment");
                CommentRemote[] ans = new CommentRemote[bean.size()];
                for (int i = 0; i < bean.size(); i++) {
                    ((RootDataBeanRemote) (bean.toArray()[i])).setSessionKey(sessionKey);
                    ans[i] = drh.create((RootDataBeanRemote) (bean.toArray()[i]),sessionKey);
                }
                return ans;
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new RemoteException(default_object_type+".getComments: " + e.getLocalizedMessage());
        }
    }

    public void addComment(Arch doc) throws RemoteException {
        try {
            CommentRemoteHome drh = (CommentRemoteHome) (new InitialContext()).lookup("ejb/Comment");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, getKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__COMMENT_PARENT, getKey().toString()));
            CommentRemote newcom = drh.create(doc,sessionKey);
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:" + default_object_type + ":addComment: " + e.getLocalizedMessage());
            throw new RemoteException("ERROR:" + default_object_type + ":addComment: " + e.getLocalizedMessage());
        }
    }

    public void addComment(Arch doc, Long fromKey) throws RemoteException {
        try {
            CommentRemoteHome drh = (CommentRemoteHome) (new InitialContext()).lookup("ejb/Comment");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, getKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__COMMENT_PARENT, getKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__COMMENT_AUTHOR, fromKey.toString()));
            CommentRemote newcom = drh.create(doc,sessionKey);
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:" + default_object_type + ":addComment: " + e.getLocalizedMessage());
            throw new RemoteException("ERROR:" + default_object_type + ":addComment: " + e.getLocalizedMessage());
        }
    }

    public String getName() throws RemoteException {
        return dataBean.getParameter(Consts.ATTR__FOLDER_NAME);
    }

    public FileRemote[] getFiles() throws RemoteException {
        try {
            FileRemoteHome drh =
                    (FileRemoteHome) (new InitialContext()).lookup("ejb/File");
            RootDataBeanRemoteHome rdbrh =
                    (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            Collection bean = rdbrh.findByParentKey(this.getKey(), Consts.OBJECT_TYPE__FILE);
            FileRemote[] ans = new FileRemote[bean.size()];
            for (int i = 0; i < bean.size(); i++) {
                ((RootDataBeanRemote) (bean.toArray()[i])).setSessionKey(sessionKey);
                ans[i] = drh.create((RootDataBeanRemote) (bean.toArray()[i]),sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("Folder.detFiles: " + e.getLocalizedMessage());
        }
    }

    public FileRemote addFile(Arch doc) throws RemoteException {
        try {
            FileRemoteHome drh = (FileRemoteHome) (new InitialContext()).lookup("ejb/File");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, dataBean.getPrimaryKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__FILE_CONTEXT, getContext().getKey().toString()));
            if (doc.getChild(Consts.ATTR__FILE_AUTHOR) == null) {
                doc.addChild(new ArchImpl(Consts.ATTR__FILE_AUTHOR,
                        getAuthor().getKey().toString()));
            }
            FileRemote DR = drh.create(doc,sessionKey);
            if (Consts.DEBUG_MODE) System.out.println("Folder.addFile: created ");
            return DR;
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:Folder.addFile: " + e.getLocalizedMessage());
            throw new RemoteException("Folder.addFile: " + e.getLocalizedMessage());
        }
    }

    public FolderRemote[] getFolders() throws RemoteException {
        try {
            FolderRemoteHome drh =
                    (FolderRemoteHome) (new InitialContext()).lookup("ejb/Folder");
            RootDataBeanRemoteHome rdbrh =
                    (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            Collection bean = rdbrh.findByParentKey(this.getKey(), Consts.OBJECT_TYPE__FOLDER);
            FolderRemote[] ans = new FolderRemote[bean.size()];
            for (int i = 0; i < bean.size(); i++) {
                ((RootDataBeanRemote) (bean.toArray()[i])).setSessionKey(sessionKey);
                ans[i] = drh.create((RootDataBeanRemote) (bean.toArray()[i]),sessionKey);
            }
            return ans;
        } catch (Exception e) {
            throw new RemoteException("Folder.detFolders: " + e.getLocalizedMessage());
        }
    }

    public void addFolder(Arch doc) throws RemoteException {
        try {
            FolderRemoteHome drh = (FolderRemoteHome) (new InitialContext()).lookup("ejb/Folder");
            doc.addChild(new ArchImpl(Consts.ARCH_F_PARENT, dataBean.getPrimaryKey().toString()));
            doc.addChild(new ArchImpl(Consts.ATTR__FOLDER_CONTEXT, getContext().getKey().toString()));
            if (doc.getChild(Consts.ATTR__FOLDER_AUTHOR) == null) {
                doc.addChild(new ArchImpl(Consts.ATTR__FOLDER_AUTHOR,
                        getAuthor().getKey().toString()));
            }
            FolderRemote DR = drh.create(doc,sessionKey);
            if (Consts.DEBUG_MODE) System.out.println("Folder.addFolder: created ");
        } catch (Exception e) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR:Folder.addFolder: " + e.getLocalizedMessage());
            throw new RemoteException("Folder.addFolder: " + e.getLocalizedMessage());
        }
    }

    public void dropMe() throws RemoteException {
        try {
            dataBean.dropMe();
        } catch (Exception e) {
            throw new RemoteException(e.getLocalizedMessage());
        }
    }

    public UserRemote getAuthor() throws RemoteException {
        String key = dataBean.getParameter(Consts.ATTR__FOLDER_AUTHOR);
        return (UserRemote) ModelFactory.getByKey(new Long(Long.parseLong(key)),sessionKey);
    }
    
    public Postable getContext() throws RemoteException {
        String key = dataBean.getParameter(Consts.ATTR__FOLDER_CONTEXT);
        if (key != null) {
            return (Postable) ModelFactory.getByKey(new Long(Long.parseLong(key)), sessionKey);
        } else {
            return (Postable) getAuthor();
        }
    }

    public List getRolesForUser(Long key) throws RemoteException {
        List ans = new ArrayList();
        if (dataBean.isAuthor(key)) {
            Arch doc = new ArchImpl("root", null);
            doc.addChild(new ArchImpl(Consts.ATTR__ROLE_NAME, Consts.ROLE_OWNER));
            try {
                RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
                RootDataBeanRemote rdbr = rdbrh.findByFieldSet(doc, Consts.OBJECT_TYPE__ROLE);
                rdbr.setSessionKey(sessionKey);
                RoleRemoteHome rrh = (RoleRemoteHome) (new InitialContext()).lookup("ejb/Role");
                RoleRemote rr = rrh.create(rdbr, sessionKey);
                rr.setLevel(Consts.ROLE_LEVEL_FOLDER);
                ans.add(rr);

            } catch (Exception e) {
                throw new RemoteException(default_object_type+"getRoleForUser: " + e.getLocalizedMessage());
            }
        }
        if (getParent() != null) {
            ans.addAll(getParent().getRolesForUser(key));
        }
        return ans;
    }

    public String getType() throws RemoteException {
        return default_object_type;
    }
}
